﻿using CentralVacuum.Common;
using CentralVacuum.Communication;
using CentralVacuum.Models;
using HslCommunication;
using HslCommunication.MQTT;
using Newtonsoft.Json;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CentralVacuum.Mqtt
{
    public static class HslMqtt
    {
        public static MqttClient mqttClient;
        public static OperateResult connect;
        private static string original, appliance;
        //public static string originalRemote;
        public static void OpenConnect(string ip, int port, string user, string password)
        {
            IniFile ini = new IniFile(@"C:\FangYuanData\Setting.ini");
            appliance = ini.ReadString("System", "Appliance", "");

            IniFile ini1 = new IniFile(@"C:\FangYuanData\PN.ini");
            Global.originalRemote = ini1.ReadString("System", "PN", "");

            original = Global.GetCpuInfo();//授权码
            //originalRemote = "BFEBFBFF00090661";
            // 打开本地MQTT服务器
            try
            {
                MqttServer server = new MqttServer();
                server.ServerStart(port);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Start Failed: " + ex.Message);
                Global.LogNet.WriteFatal("MQTT", "MQTT本地服务器打开失败!");
            }

            //云服务器
            mqttClient = new MqttClient(new MqttConnectionOptions()
            {
                ClientId = original + "_" + Guid.NewGuid().ToString(),       // 客户端唯一的ID信息
                IpAddress = ip,                                              // 服务器的地址，外部公网"60.191.66.212"本地公网"172.28.1.153"本地"127.0.0.1"
                Port = port,                                                 // 端口默认1883
                Credentials = new MqttCredential(user.ToLower(), password)   // 设置了默认用户名(admin)和密码(123456)
            });
            connect = mqttClient.ConnectServer();

            if (connect.IsSuccess)
            {
                Task.Run(() =>
                {
                    RunWork();
                });
                Console.WriteLine("MQTT云服务器连接成功!");
                Global.LogNet.WriteInfo("MQTT", "MQTT云服务器连接成功!");
            }
            else
            {
                Console.WriteLine("MQTT云服务器连接失败!");
                Global.LogNet.WriteInfo("MQTT", "MQTT云服务器连接失败!");
            }
        }

        private static void RunWork()
        {
            // 网络失败的情况，需要自己来手动控制重连，实例化后进行事件绑定
            mqttClient.OnNetworkError += (object sender, EventArgs e) =>
            {
                // 当网络异常的时候触发，可以在此处重连服务器
                if (sender is MqttClient client)
                {
                    // 开始重连服务器，直到连接成功为止
                    Global.LogNet.WriteInfo("MQTT", "网络异常，准备10秒后重新循环连接。");
                    
                    while (true)
                    {
                        //Global.LogNet.WriteInfo("准备重新连接服务器...");
                        connect = client.ConnectServer();
                        if (connect.IsSuccess)
                        {
                            // 连接成功后，可以在下方break之前进行订阅，或是数据初始化操作
                            Global.LogNet.WriteInfo("MQTT", "MQTT云服务器重新连接成功!");
                            // 然后添加订阅
                            XMSubscribeTopic();
                            break;
                        }
                        // 每隔10秒重连
                        Thread.Sleep(10000);
                        //Global.LogNet.WriteInfo("连接失败，准备10秒后重新连接。");
                    }
                }
            };

            // 订阅示例
            mqttClient.OnMqttMessageReceived += (MqttClient client, MqttApplicationMessage message) =>
            {
                string stateReturn = "";
                if (appliance.ToLower() == "server")//本地服务端
                {
                    try
                    {
                        PersonModel person = JsonConvert.DeserializeObject<PersonModel>(Encoding.UTF8.GetString(message.Payload));//将JSON转化为类数据（反序列化）
                        Console.WriteLine("Time:" + DateTime.Now.ToString());
                        Console.WriteLine("Topic:" + message.Topic);
                        Console.WriteLine("Payload:" + Encoding.UTF8.GetString(message.Payload));
                        //反写数据到PLC
                        HslMelsecMCBinary.XMMqttWritePlc(person);//从mqtt写入到PLC
                        stateReturn = "success";
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Format Failed: " + ex.Message);
                        stateReturn = ex.Message;
                    }
                    // 发布数据
                    _ = mqttClient.PublishMessage(new MqttApplicationMessage()
                    {
                        Topic = "result/" + original,                                            // 主题
                        QualityOfServiceLevel = MqttQualityOfServiceLevel.ExactlyOnce,           // 只有一次
                        Payload = Encoding.UTF8.GetBytes(stateReturn)                            // 发布的数据
                    });
                }
                else if (appliance.ToLower() == "client")
                {
                    try
                    {
                        Register person = JsonConvert.DeserializeObject<Register>(Encoding.UTF8.GetString(message.Payload));//将JSON转化为类数据（反序列化）
                        /*Console.WriteLine("Time:" + DateTime.Now.ToString());
                        Console.WriteLine("Topic:" + message.Topic);
                        Console.WriteLine("Payload:" + Encoding.UTF8.GetString(message.Payload));*/
                        //获取MQTT服务器的数据到UI画面
                        Global.rMQTTData = person;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Format Failed: " + ex.Message);
                    }
                }
            };

            // 然后添加订阅
            XMSubscribeTopic();
            while (appliance.ToLower() == "server")
            {
                if (connect.IsSuccess)
                {
                    Thread.Sleep(100);//设置采集周期
                    
                        // 数据采集
                        string json = JsonConvert.SerializeObject(Global.rData);//将类转化为JSON（序列化）
                        //Register person = JsonConvert.DeserializeObject<Register>(json);//将JSON转化为类数据（反序列化）

                        // 发布数据
                        _ = mqttClient.PublishMessage(new MqttApplicationMessage()
                        {
                            Topic = "data/" + original,                                            // 主题
                            QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce,          // 如果是实时数据，适合用这个
                            Payload = Encoding.UTF8.GetBytes(json)                                 // 发布的数据
                        });
                }
            } 
        }

        private static void XMSubscribeTopic()
        {
            if (appliance.ToLower() == "server")//本地服务端
            {
                _ = mqttClient.SubscribeMessage("cmd/" + original);
                
            }
            else if (appliance.ToLower() == "client")//远程客户端
            {
                _ = mqttClient.SubscribeMessage("data/" + Global.originalRemote);
            }
        }

        public static void personModelToMqtt(PersonModel person)
        {
            // 数据采集
            string json = JsonConvert.SerializeObject(person);//将类转化为JSON（序列化）
            //Register person = JsonConvert.DeserializeObject<Register>(json);//将JSON转化为类数据（反序列化）

            // 发布数据
            OperateResult connect = HslMqtt.mqttClient.PublishMessage(new MqttApplicationMessage()
            {
                Topic = "cmd/" + Global.originalRemote,                                // 主题
                QualityOfServiceLevel = MqttQualityOfServiceLevel.ExactlyOnce,          // 如果是实时数据，适合用这个
                Payload = Encoding.UTF8.GetBytes(json)                                  // 发布的数据
            });
            if (connect.IsSuccess)
                Console.WriteLine("MQTT发布成功:" + json);
            else
                Console.WriteLine("MQTT发布失败");
        }
            

        /// <summary>
        /// 发布日志数据到mqtt
        /// </summary>
        /// <param name="pLog">日志类</param>
        public static void pLogToMqtt(PLog pLog)
        {
            if (appliance.ToLower() == "server")
            {
                if (connect.IsSuccess)
                {
                    // 数据采集
                    string json = JsonConvert.SerializeObject(pLog);//将类转化为JSON（序列化）

                    // 发布数据
                    _ = mqttClient.PublishMessage(new MqttApplicationMessage()
                    {
                        Topic = "plog/" + original,                                            // 主题
                        QualityOfServiceLevel = MqttQualityOfServiceLevel.ExactlyOnce,         // 日志数据，适合用这个
                        Payload = Encoding.UTF8.GetBytes(json)                                 // 发布的数据
                    });
                }
            }
        }

        /// <summary>
        /// 配方数据到mqtt
        /// </summary>
        /// <param name="recipe">配方类</param>
        public static void recipeToMqtt(Recipe recipe)
        {
            if (appliance.ToLower() == "server")
            {
                if (connect.IsSuccess)
                {
                    // 数据采集
                    string json = JsonConvert.SerializeObject(recipe);//将类转化为JSON（序列化）

                    // 发布数据
                    _ = mqttClient.PublishMessage(new MqttApplicationMessage()
                    {
                        Topic = "recipe/" + original,                                            // 主题
                        QualityOfServiceLevel = MqttQualityOfServiceLevel.ExactlyOnce,         // 日志数据，适合用这个
                        Payload = Encoding.UTF8.GetBytes(json)                                 // 发布的数据
                    });
                }
            }
        }

        
    }
}
